package smart.rpc.client;

import com.alibaba.fastjson.JSONObject;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import smart.rpc.common.SmartRPCRequest;
import smart.rpc.common.SmartRPCResponse;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created By gao_e on 2020/3/10 18:32
 * 客户端 NIO 具体操作
 */
public class NettyClientChannelHandler extends ChannelInboundHandlerAdapter {

    private StartNettyClientConnectTask startNettyClientConnectTask;

    public NettyClientChannelHandler(StartNettyClientConnectTask startNettyClientConnectTask) {
        this.startNettyClientConnectTask = startNettyClientConnectTask;
    }

    public NettyClientChannelHandler() {

    }

    // 用独立的线程做 IO 写出 操作
    private ExecutorService executorService = Executors.newFixedThreadPool(6);

    /**
     * @param ctx
     * @throws Exception
     * 信道激活
     * 连接服务端就绪，准备开写请求数据
     * Created By gao_e on 2020/3/10 18:32
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("...............开始执行请求写出操作...............");
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    SmartRPCRequest request = startNettyClientConnectTask.handedARequest();
                    String requestJson = JSONObject.toJSONString(request);
                    ctx.writeAndFlush(requestJson);
                    ctx.flush();
                }
            }
        });
    }
    private ExecutorService executorService2 = Executors.newSingleThreadExecutor();
    /**
     * @param ctx
     * @param msg
     * @throws Exception
     * 信道读取，获取服务端响应结果
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("Get result msg = " + msg + " , msg class = " + msg.getClass().getSimpleName());
        SmartRPCResponse smartRPCResponse = JSONObject.parseObject((String) msg, SmartRPCResponse.class);
        // 操作结果
        executorService2.execute(new Runnable() {
            @Override
            public void run() {
                startNettyClientConnectTask.receiveAResponse(smartRPCResponse);
            }
        });
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("unexpected exception from downstream : " + cause.getMessage());
        ctx.close();
    }

}
